package com.hft.utils;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
 * 
 *汇付天下有限公司
 * Copyright (c) 2006-2013 ChinaPnR,Inc.All Rights Reserved.
 */

/**
 * 
 * @author feitao.huang
 * @version Id: NumberDecoder.java, v 0.1 2013-10-12 下午04:48:29 feitao.huang Exp 
 */
public class NumberUtils {
    private static final String[]             SEED62ARRAY = { "0", "1", "2", "3", "4", "5", "6",
            "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E",
            "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z"                           };
    private static final Map<String, Integer> SEED62MAP   = initSEED62MAP();

    /**
     * 返回将十进制数转换为指定进制的数的字符串形式
     * @param dec       需要转换的十进制数字
     * @param devider    输出进制。从2进制到62进制均支持，当不在此进制范围,返回null
     * @return    指定输出进制的数字
     * @throws Exception 
     */
    public static String dec2any(String dec, int targetDevider) {
        if (targetDevider == 10)
            return dec;
        if (targetDevider > 62 || targetDevider < 2 || null == dec || "".equals(dec.trim()))
            return null;
        try {
            long devider = Long.parseLong(String.valueOf(targetDevider));//进制    
            long dividend = Long.parseLong(dec);//被除数
            long consult = 0L;//轮商
            long remainder = 0L;//轮余
            StringBuffer sb = new StringBuffer();//余数累加
            while (true) {
                remainder = dividend % devider;
                consult = dividend / devider;
                sb.append(SEED62ARRAY[(int) remainder]);
                if (consult < devider) {
                    sb.append(SEED62ARRAY[(int) consult]);
                    break;
                }
                dividend = consult;
            }
            String ret =  sb.reverse().toString();
            //过滤以0开头并且长度为一位的,特例6转62进制，得到06
            if(ret.length() > 1 && "0".equals(String.valueOf(ret.charAt(0)))){
            	ret = ret.replaceFirst("0", StringUtils.EMPTY);
            }
            return ret;
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 进制的任意转换
     * 返回一个已知进制的数的其他进制的值
     * @param sourceNum 需转换数的字符串
     * @param soruceDevider 需转换数的进制
     * @param targetDevider 目标进制
     * @return 目标进制的字符串
     */
    public static String any2any(String sourceNum, int soruceDevider, int targetDevider) {
        if (targetDevider > 62 || targetDevider < 2 || soruceDevider > 62 || soruceDevider < 2)
            return null;
        if (null == sourceNum || "".equals(sourceNum.trim()))
            return null;
        if (soruceDevider == targetDevider)
            return sourceNum;
        return dec2any(any2dec(sourceNum, soruceDevider), targetDevider);
    }

    /**
     * 返回一个已知进制的数的十进制的值
     * @param String 需转换数的字符串
     * @param int 需转换数的进制
     * @return 转换后的数的字符串
     */
    public static String any2dec(String sourceNum, int soruceDevider) {
        if (soruceDevider == 10)
            return sourceNum;
        if (soruceDevider > 62 || soruceDevider < 2 || null == sourceNum
            || "".equals(sourceNum.trim()))
            return null;
        try {
            long sum = 0L;
            for (int i = 0; i < sourceNum.length(); i++) {
                int k = SEED62MAP.get(String.valueOf(sourceNum.charAt(i)));
                if (k >= soruceDevider)
                    return null;
                sum += k * Math.pow(soruceDevider, sourceNum.length() - (i + 1));
            }
            return String.valueOf(sum);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 初始化map
     * 此Map存储进制数对应的十进制值键值对，比如a=10，A=27，Z=61
     * @return map
     */
    private static Map<String, Integer> initSEED62MAP() {
        Map<String, Integer> map = new HashMap<String, Integer>();
        for (int i = 0; i < 62; i++) {
            map.put(SEED62ARRAY[i], i);
        }
        return map;
    }
}
